import type { ParallelTaskExecuteContext } from '../handler'

import type { ProcessorWorkerReplyWorkerMessage, ProcessorWorkerSendWorkerMessage } from '../worker'
import { ParallelHandler } from '../handler'

// eslint-disable-next-line ts/ban-ts-comment
// @ts-ignore
import ProcessorWorker from '../worker/processor.worker?worker&inline'

class ProcessorAudio extends ParallelHandler<Float32Array, Array<number>> {
  private processorWorkerInstance: Worker | null = null

  protected onActive(): void {
    this.processorWorkerInstance = new ProcessorWorker()

    this.processorWorkerInstance?.addEventListener('message', (event: MessageEvent<ProcessorWorkerReplyWorkerMessage>): void => {
      const { type, data } = event.data
      if (type === 'success') {
        const { audioData } = data
        this.forwardToHandler(audioData)
      }
      this.taskCompletedCallback(data.uuid)
    })
  }

  public execute(context: ParallelTaskExecuteContext<Float32Array, Array<number>>): void {
    if (context.isLastExecute) {
      this.taskCompletedCallback(context.taskItem.uuid)
      return
    }

    this.processorWorkerInstance?.postMessage({
      type: 'send',
      data: context.taskItem,
    } as ProcessorWorkerSendWorkerMessage)
  }

  protected onFinish(): void {
    if (this.processorWorkerInstance) {
      this.processorWorkerInstance.terminate()
    }
    this.processorWorkerInstance = null
    this.executeController?.$bus.emit('_processorAudioFinish')
  }
}

export default ProcessorAudio
